// ///////////////////////////// MIT License //////////////////////////////////// //
//                                                                                //
// Copyright (c) 2010 David Zsolt Manrique                                        //
//                    david.zsolt.manrique@gmail.com                              //
//                                                                                //
// Permission is hereby granted, free of charge, to any person obtaining a copy   //
// of this software and associated documentation files (the "Software"), to deal  //
// in the Software without restriction, including without limitation the rights   //
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      //
// copies of the Software, and to permit persons to whom the Software is          //
// furnished to do so, subject to the following conditions:                       //
//                                                                                //
// The above copyright notice and this permission notice shall be included in     //
// all copies or substantial portions of the Software.                            //
//                                                                                //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     //
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    //
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         //
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  //
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN      //
// THE SOFTWARE.                                                                  //
//                                                                                //
// ////////////////////////////////////////////////////////////////////////////// //

#include "structure_io.h"
#include "potential.h"
#include "integrate.h"

#include "xyz.h"

int main(int argc, char** argv)
{
try
{	
	io::arguments arg(argc,argv);
	io::switcharg<false> help(arg,"-h","--help", "print help message");
	io::switcharg<false> version(arg,"-v","--version", "print version info");
	io::switcharg<false> interact(arg,"-i","--interactions", "print interaction list");
	io::posarg<std::string> input_fn(arg,"input file name", "");
	io::posarg<std::string> output_fn(arg,"output file name", "");
	
	if(*help)
	{
		arg.print_help(std::cout,"mdtool");
		return EXIT_SUCCESS;
	}
	if(*version)
	{
		std::cout << "version 0.6" << std::endl;
		return EXIT_SUCCESS;
	}
	 
	// input output streams 
	io::input_stream input(*input_fn); 
	io::output_stream output(*output_fn); 
	 
	std::istream &is = input.stream();
	std::ostream &os = output.stream();

	std::vector<std::string> input_lines;
	io::load(is,"#",input_lines);

	structure_t sp;
	input_lines >> sp;

	if(*interact)
	{
		os << sp;
		return EXIT_SUCCESS;
	}

	steepest_descent_control sdc;
	if(input_lines>>=sdc)
	{
		steepest_descent sd(sdc);
		sd(os,sp.atom_list.position,sp);
	}

	velocity_verlet_control vvc;
	if(input_lines>>=vvc)
	{
		velocity_verlet vv(sp.atom_list.mass,sp.potential_list,sp.atom_list.fixed);
		double t = vvc.t0;
		position_t r = sp.atom_list.position;
		velocity_t v = sp.atom_list.velocity;
		vector_array_type f(r.size());
		unitcell_t uc = sp.unitcell;
		real_type u = 0.0;
		while(t < vvc.t1)
		{	
			vv(t,vvc.dt,vvc.DT,r,v,f,u,uc);
			io::xyz<vector_type> out;
			out.set(uc.col(0),uc.col(1),uc.col(2),sp.atom_list.label,r,v,f);
			real_type kin = kinetic_energy(sp.atom_list.mass,v);  //! What if we fix and add initial velocity?
			out.var_double("kinetic")=kin;
			out.var_double("potential")=u;
			out.var_double("total")=u+kin;
			os << out;
		}
	}
			

} catch(const char* message)
{
	std::cerr << message << std::endl;
	std::cerr << "(exit)" << std::endl;
	return EXIT_FAILURE;
} 
catch(const std::exception & e)
{
	std::cerr << e.what() << std::endl;
	std::cerr << "(exit)" << std::endl;
	return EXIT_FAILURE;
}
	return EXIT_SUCCESS;
}

/*
int main(int argc, char** argv)
{


	std::stringstream text;

	text << "<initial-position>  " << std::endl;
	text << "1  0.0  0.0  0.0 " << std::endl;
	text << "2  1.0  0.0  0.0 " << std::endl;
	text << "3  0.0  1.0  0.0 " << std::endl;
	text << "4  0.0  0.0  1.0 " << std::endl;
	text << "<\\initial-position>  " << std::endl;
	text << "<label>  " << std::endl;
	text << "1:4  H " << std::endl;
	text << "<\\label>  " << std::endl;
	text << "<initial-velocity>  " << std::endl;
	text << "1  0.0  0.0  0.0 " << std::endl;
	text << "2  1.0  0.0  0.0 " << std::endl;
	text << "3  0.0  1.0  0.0 " << std::endl;
	text << "4  0.0  0.0  1.0 " << std::endl;
	text << "<\\initial-velocity>  " << std::endl;
	text << "<mass>  " << std::endl;
	text << "1:4  1.0 " << std::endl;
	text << "<\\mass>  " << std::endl;
	text << "<charge>  " << std::endl;
	text << "1:4  0.0 " << std::endl;
	text << "<\\charge>  " << std::endl;
	text << "<topology>  " << std::endl;
	text << " 2 1 3" << std::endl;
	text << " 4 1" << std::endl;
	text << "<\\topology>  " << std::endl;
	text << "<field>  " << std::endl;
	text << "angle harm 4.5  80 :  1,2,3" << std::endl;
	text << "<\\field>  " << std::endl;
	std::vector<std::string> input_lines;
	io::load(text,"#",input_lines);

	structure_t sp;
	input_lines >> in<structure_t>(sp);
	
	std::cout << out<structure_t>(sp);

	velocity_verlet vv(0.0,1.0,0.001,0.1);
	vv(std::cout,sp.atom_list.position,sp.atom_list.velocity,sp);

	system("pause");
	return 0;
}

*/

